package cn.sunzq.springdata.elasticsearch.demo.querydemo.service.impl;

import cn.sunzq.springdata.elasticsearch.demo.base.BaseService;
import cn.sunzq.springdata.elasticsearch.demo.document.TempLincolnshireDocument;
import cn.sunzq.springdata.elasticsearch.demo.querydemo.service.TempLincolnshireDemoService;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
import org.elasticsearch.search.aggregations.bucket.histogram.ParsedDateHistogram;
import org.elasticsearch.search.aggregations.bucket.range.DateRangeAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.range.ParsedRange;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedTerms;
import org.elasticsearch.search.aggregations.metrics.*;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.Criteria;
import org.springframework.data.elasticsearch.core.query.CriteriaQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.StringQuery;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * @创建人 孙中泉
 * @创建时间 2021/7/27
 * @描述
 */
@Service
public class TempLincolnshireDemoServiceImpl extends BaseService implements TempLincolnshireDemoService {

    @Override
    public List<TempLincolnshireDocument> criteriaQuery1(String name, String year, Integer pageNo, Integer pageSize) {
        Criteria criteria = new Criteria();
        if(name != null)criteria = criteria.and("name").is(name);
        if(year != null)criteria = criteria.and("year").is(year);
        CriteriaQuery criteriaQuery = new CriteriaQuery(criteria,  PageRequest.of(pageNo - 1, pageSize));
        SearchHits<TempLincolnshireDocument> searchHits = elasticsearchOperations.search(criteriaQuery, TempLincolnshireDocument.class);
        List<SearchHit<TempLincolnshireDocument>> searchHitList = searchHits.getSearchHits();
        List<TempLincolnshireDocument> list = new LinkedList<>();
        searchHitList.stream().forEach( searchHit -> list.add(searchHit.getContent()));
        return list;
    }

    @Override
    public List<TempLincolnshireDocument> criteriaQuery2(List<String> name, List<String> year, Integer pageNo, Integer pageSize) {
        Criteria criteria = new Criteria();
        if(name != null && !name.isEmpty())criteria = criteria.and("name").in(name);
        if(year != null && !year.isEmpty())criteria = criteria.and("year").in(year);
        CriteriaQuery criteriaQuery = new CriteriaQuery(criteria,  PageRequest.of(pageNo - 1, pageSize));
        SearchHits<TempLincolnshireDocument> searchHits = elasticsearchOperations.search(criteriaQuery, TempLincolnshireDocument.class);
        List<SearchHit<TempLincolnshireDocument>> searchHitList = searchHits.getSearchHits();
        List<TempLincolnshireDocument> list = new LinkedList<>();
        searchHitList.stream().forEach( searchHit -> list.add(searchHit.getContent()));
        return list;
    }

    @Override
    public List<TempLincolnshireDocument> criteriaQuery3(String keyword, Integer pageNo, Integer pageSize) {
        Criteria criteria = new Criteria();
        if(keyword != null && !keyword.trim().isEmpty()){
            criteria = criteria.or("name").contains(keyword);
            criteria = criteria.or("year").contains(keyword);
        }
        CriteriaQuery criteriaQuery = new CriteriaQuery(criteria,  PageRequest.of(pageNo - 1, pageSize));
        SearchHits<TempLincolnshireDocument> searchHits = elasticsearchOperations.search(criteriaQuery, TempLincolnshireDocument.class);
        List<SearchHit<TempLincolnshireDocument>> searchHitList = searchHits.getSearchHits();
        List<TempLincolnshireDocument> list = new LinkedList<>();
        searchHitList.stream().forEach( searchHit -> list.add(searchHit.getContent()));
        return list;
    }

    @Override
    public List<TempLincolnshireDocument> stringQuery1(String name, String year, Integer pageNo, Integer pageSize) {
        //match
        StringQuery stringQuery = new StringQuery("{\n" +
                "    \"match\": {\n" +
                "      \"name\": \"" + name + "\"\n" +
                "    }\n" +
                "  }",PageRequest.of(pageNo - 1, pageSize));
        //term
        stringQuery = new StringQuery("{\n" +
                "    \"term\": {\n" +
                "      \"name\": {\n" +
                "        \"value\": \"" + name + "\"\n" +
                "      }\n" +
                "    }\n" +
                "  }");
        //bool下两个term
        stringQuery = new StringQuery("{\n" +
                "    \"bool\": {\n" +
                "      \"must\": [\n" +
                "        {\n" +
                "          \"term\": {\n" +
                "            \"name\": {\n" +
                "              \"value\": \"" + name + "\"\n" +
                "            }\n" +
                "          }\n" +
                "        },\n" +
                "        {\n" +
                "          \"term\": {\n" +
                "            \"year\": {\n" +
                "              \"value\": \"" + year + "\"\n" +
                "            }\n" +
                "          }\n" +
                "        }\n" +
                "      ]\n" +
                "    }\n" +
                "  }");
        System.out.println(stringQuery.getSource());
        SearchHits<TempLincolnshireDocument> searchHits = elasticsearchOperations.search(stringQuery, TempLincolnshireDocument.class);
        List<SearchHit<TempLincolnshireDocument>> searchHitList = searchHits.getSearchHits();
        List<TempLincolnshireDocument> list = new LinkedList<>();
        searchHitList.stream().forEach( searchHit -> list.add(searchHit.getContent()));




        return list;
    }

    @Override
    public List<Map<String,Object>> restClient1(String name, String year, Integer pageNo, Integer pageSize) {
        SearchRequest searchRequest = new SearchRequest();
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchRequest.indices("temp_lincolnshire").source(searchSourceBuilder);
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        List<QueryBuilder> queryBuilderList = boolQueryBuilder.must();
        queryBuilderList.add(QueryBuilders.termQuery("name", name));
        queryBuilderList.add(QueryBuilders.termQuery("year", year));
        searchSourceBuilder.query(boolQueryBuilder);
        searchSourceBuilder.size(pageSize);
        searchSourceBuilder.from(pageNo * (pageNo - 1));
        SearchResponse searchResponse = null;
        try {
            searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        List<Map<String,Object>> list = new LinkedList<>();
        if(searchResponse != null){
            org.elasticsearch.search.SearchHits searchHits = searchResponse.getHits();
            org.elasticsearch.search.SearchHit[] hits = searchHits.getHits();
            for (org.elasticsearch.search.SearchHit searchHit : hits) {
                list.add(searchHit.getSourceAsMap());
            }
        }
        return list;
    }

    @Override
    public Map<String, Object> aggDemo1(String name, String year) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        List<QueryBuilder> queryBuilderList = boolQueryBuilder.must();
        queryBuilderList.add(QueryBuilders.termQuery("name", name));
        queryBuilderList.add(QueryBuilders.termQuery("year", year));
        AbstractAggregationBuilder abstractAggregationBuilder = AggregationBuilders.terms("hours").field("hours");
        NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(boolQueryBuilder);
        nativeSearchQuery.addAggregation(abstractAggregationBuilder);
        nativeSearchQuery.setPageable(PageRequest.of(0,1));
        SearchHits searchHits = elasticsearchOperations.search(nativeSearchQuery, TempLincolnshireDocument.class);
        Aggregations aggregations = searchHits.getAggregations();
        ParsedStringTerms parsedStringTerms = aggregations.get("hours");
        List<ParsedStringTerms.ParsedBucket> buckets = (List<ParsedStringTerms.ParsedBucket>)parsedStringTerms.getBuckets();
        Map<String, Object> map = new HashMap<>();
        for (ParsedStringTerms.ParsedBucket bucket : buckets) {
            String key = bucket.getKeyAsString();
            long count = bucket.getDocCount();
            map.put(key, count);
        }
        return map;
    }

    @Override
    public List<Map<String, Object>> aggDemo2(String name, String year) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        List<QueryBuilder> queryBuilderList = boolQueryBuilder.must();
        queryBuilderList.add(QueryBuilders.termQuery("name", name));
        queryBuilderList.add(QueryBuilders.termQuery("year", year));
        AbstractAggregationBuilder monthBuilder = AggregationBuilders.terms("month").field("month");
        AbstractAggregationBuilder hoursBuilder = AggregationBuilders.terms("hours").field("hours");
        NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(boolQueryBuilder);
        nativeSearchQuery.addAggregation(monthBuilder);
        nativeSearchQuery.addAggregation(hoursBuilder);
        nativeSearchQuery.setPageable(PageRequest.of(0,1));

        System.out.println("boolQueryBuilder:" + boolQueryBuilder.toString());
        System.out.println("monthBuilder:" + monthBuilder.toString());
        System.out.println("hoursBuilder:" + hoursBuilder.toString());
        SearchHits searchHits = elasticsearchOperations.search(nativeSearchQuery, TempLincolnshireDocument.class);


        List<Map<String,Object>> mapList = new LinkedList<>();
        Aggregations aggregations = searchHits.getAggregations();

        ParsedStringTerms hoursParsedStringTerms = aggregations.get("hours");
        List<ParsedStringTerms.ParsedBucket> hoursBuckets = (List<ParsedStringTerms.ParsedBucket>)hoursParsedStringTerms.getBuckets();
        Map<String, Object> hoursMap = new HashMap<>();
        for (ParsedStringTerms.ParsedBucket bucket : hoursBuckets) {
            String key = bucket.getKeyAsString();
            long count = bucket.getDocCount();
            hoursMap.put(key, count);
        }
        mapList.add(hoursMap);

        ParsedStringTerms monthParsedStringTerms = aggregations.get("month");
        List<ParsedStringTerms.ParsedBucket> monthBuckets = (List<ParsedStringTerms.ParsedBucket>)monthParsedStringTerms.getBuckets();
        Map<String, Object> monthMap = new HashMap<>();
        for (ParsedStringTerms.ParsedBucket bucket : monthBuckets) {
            String key = bucket.getKeyAsString();
            long count = bucket.getDocCount();
            monthMap.put(key, count);
        }
        mapList.add(monthMap);

        return mapList;
    }

    @Override
    public List<Map<String, Object>> aggDemo3(String name, String year) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        List<QueryBuilder> queryBuilderList = boolQueryBuilder.must();
        queryBuilderList.add(QueryBuilders.termQuery("name", name));
        queryBuilderList.add(QueryBuilders.termQuery("year", year));

        AbstractAggregationBuilder monthBuilder = AggregationBuilders.terms("month").field("month");
        monthBuilder.subAggregation(AggregationBuilders.avg("value").field("value"));

        AbstractAggregationBuilder hoursBuilder = AggregationBuilders.terms("hours").field("hours");
        hoursBuilder.subAggregation(AggregationBuilders.avg("value").field("value"));


        NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(boolQueryBuilder);
        nativeSearchQuery.addAggregation(monthBuilder);
        nativeSearchQuery.addAggregation(hoursBuilder);
        nativeSearchQuery.setPageable(PageRequest.of(0,1));

        System.out.println("boolQueryBuilder:" + boolQueryBuilder.toString());
        System.out.println("monthBuilder:" + monthBuilder.toString());
        System.out.println("hoursBuilder:" + hoursBuilder.toString());
        SearchHits searchHits = elasticsearchOperations.search(nativeSearchQuery, TempLincolnshireDocument.class);


        List<Map<String,Object>> mapList = new LinkedList<>();
        Aggregations aggregations = searchHits.getAggregations();

        ParsedStringTerms hoursParsedStringTerms = aggregations.get("hours");
        List<ParsedStringTerms.ParsedBucket> hoursBuckets = (List<ParsedStringTerms.ParsedBucket>)hoursParsedStringTerms.getBuckets();
        Map<String, Object> hoursMap = new HashMap<>();
        for (ParsedStringTerms.ParsedBucket bucket : hoursBuckets) {
            String key = bucket.getKeyAsString();
            Aggregations innerAgg = bucket.getAggregations();
            ParsedAvg parsedAvg = innerAgg.get("value");
            double avg = parsedAvg.getValue();
//            long count = bucket.getDocCount();
            hoursMap.put(key, avg);
        }
        mapList.add(hoursMap);

        ParsedStringTerms monthParsedStringTerms = aggregations.get("month");
        List<ParsedStringTerms.ParsedBucket> monthBuckets = (List<ParsedStringTerms.ParsedBucket>)monthParsedStringTerms.getBuckets();
        Map<String, Object> monthMap = new HashMap<>();
        for (ParsedStringTerms.ParsedBucket bucket : monthBuckets) {
            String key = bucket.getKeyAsString();
            Aggregations innerAgg = bucket.getAggregations();
            ParsedAvg parsedAvg = innerAgg.get("value");
            double avg = parsedAvg.getValue();
            hoursMap.put(key, avg);
//            long count = bucket.getDocCount();
            monthMap.put(key, avg);
        }
        mapList.add(monthMap);

        return mapList;
    }

    @Override
    public List<Map<String, Object>> aggDemo4(String name, String year, List<Double> valueGroup) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        List<QueryBuilder> queryBuilderList = boolQueryBuilder.must();
        queryBuilderList.add(QueryBuilders.termQuery("name", name));
        queryBuilderList.add(QueryBuilders.termQuery("year", year));

        AbstractAggregationBuilder monthBuilder = AggregationBuilders.terms("month").field("month");
        DateRangeAggregationBuilder monthDateRangeAggregationBuilder = AggregationBuilders.dateRange("value").field("value");


        AbstractAggregationBuilder hoursBuilder = AggregationBuilders.terms("hours").field("hours");
        DateRangeAggregationBuilder hourDateRangeAggregationBuilder = AggregationBuilders.dateRange("value").field("value");
        for (int i = 0; i < valueGroup.size(); i++) {
            if(i == valueGroup.size() - 1){
                hourDateRangeAggregationBuilder.addUnboundedFrom(valueGroup.get(i) + "-*", valueGroup.get(i));
                monthDateRangeAggregationBuilder.addUnboundedFrom(valueGroup.get(i) + "-*", valueGroup.get(i));
            }else if(i == 0){
                hourDateRangeAggregationBuilder.addUnboundedTo( "*-" + valueGroup.get(i), valueGroup.get(i));
                monthDateRangeAggregationBuilder.addUnboundedTo( "*-" + valueGroup.get(i), valueGroup.get(i));
            }else {
                hourDateRangeAggregationBuilder.addRange(valueGroup.get(i),valueGroup.get(i + 1));
                monthDateRangeAggregationBuilder.addRange(valueGroup.get(i),valueGroup.get(i + 1));
            }
        }
        hoursBuilder.subAggregation(hourDateRangeAggregationBuilder);
        monthBuilder.subAggregation(monthDateRangeAggregationBuilder);


        NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(boolQueryBuilder);
        nativeSearchQuery.addAggregation(monthBuilder);
        nativeSearchQuery.addAggregation(hoursBuilder);
        nativeSearchQuery.setPageable(PageRequest.of(0,1));

        System.out.println("boolQueryBuilder:" + boolQueryBuilder.toString());
        System.out.println("monthBuilder:" + monthBuilder.toString());
        System.out.println("hoursBuilder:" + hoursBuilder.toString());
        SearchHits searchHits = elasticsearchOperations.search(nativeSearchQuery, TempLincolnshireDocument.class);


        List<Map<String,Object>> mapList = new LinkedList<>();
        Aggregations aggregations = searchHits.getAggregations();

        ParsedStringTerms hoursParsedStringTerms = aggregations.get("hours");
        List<ParsedStringTerms.ParsedBucket> hoursBuckets = (List<ParsedStringTerms.ParsedBucket>)hoursParsedStringTerms.getBuckets();
        Map<String, Object> hoursMap = new HashMap<>();
        for (ParsedStringTerms.ParsedBucket bucket : hoursBuckets) {
            String key = bucket.getKeyAsString();
            Aggregations innerAgg = bucket.getAggregations();
            ParsedRange parsedRange = innerAgg.get("value");
            List<ParsedRange.ParsedBucket> list = (List<ParsedRange.ParsedBucket>)parsedRange.getBuckets();
            Map<String, Object> map = new HashMap<>();
            for (ParsedRange.ParsedBucket parsedBucket : list) {
                map.put(parsedBucket.getKeyAsString(), parsedBucket.getDocCount());
            }
            hoursMap.put(key, map);
        }
        mapList.add(hoursMap);

        ParsedStringTerms monthParsedStringTerms = aggregations.get("month");
        List<ParsedStringTerms.ParsedBucket> monthBuckets = (List<ParsedStringTerms.ParsedBucket>)monthParsedStringTerms.getBuckets();
        Map<String, Object> monthMap = new HashMap<>();
        for (ParsedStringTerms.ParsedBucket bucket : monthBuckets) {
            String key = bucket.getKeyAsString();
            Aggregations innerAgg = bucket.getAggregations();
            ParsedRange parsedRange = innerAgg.get("value");
            List<ParsedRange.ParsedBucket> list = (List<ParsedRange.ParsedBucket>)parsedRange.getBuckets();
            Map<String, Object> map = new HashMap<>();
            for (ParsedRange.ParsedBucket parsedBucket : list) {
                map.put(parsedBucket.getKeyAsString(), parsedBucket.getDocCount());
            }
            monthMap.put(key, map);
        }
        mapList.add(monthMap);

        return mapList;
    }

    @Override
    public List<Map<String, Object>> aggDemo5(String  dateRangeStart, String dateRangeEnd) {
        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("time").from(dateRangeStart).to(dateRangeEnd);
        System.out.println("rangeQueryBuilder:" + rangeQueryBuilder.toString());

        DateHistogramAggregationBuilder yearBuilder = AggregationBuilders.dateHistogram("year").field("time").calendarInterval(DateHistogramInterval.YEAR).format("yyyy").minDocCount(1);
        DateHistogramAggregationBuilder monthBuilder = AggregationBuilders.dateHistogram("month").field("time").calendarInterval(DateHistogramInterval.MONTH).format("MM").minDocCount(1);
        DateHistogramAggregationBuilder dayBuilder = AggregationBuilders.dateHistogram("day").field("time").calendarInterval(DateHistogramInterval.DAY).format("dd").minDocCount(1);
        DateHistogramAggregationBuilder hourBuilder = AggregationBuilders.dateHistogram("hour").field("time").calendarInterval(DateHistogramInterval.HOUR).format("HH").minDocCount(1);
        AvgAggregationBuilder avgBuilder = AggregationBuilders.avg("avg").field("value");
        MaxAggregationBuilder maxBuilder = AggregationBuilders.max("max").field("value");
        MinAggregationBuilder minBuilder = AggregationBuilders.min("min").field("value");

        hourBuilder.subAggregation(avgBuilder);
        hourBuilder.subAggregation(maxBuilder);
        hourBuilder.subAggregation(minBuilder);
        dayBuilder.subAggregation(hourBuilder);
        monthBuilder.subAggregation(dayBuilder);
        yearBuilder.subAggregation(monthBuilder);

        System.out.println("yearBuilder:" + yearBuilder.toString());

        NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(rangeQueryBuilder);
        nativeSearchQuery.addAggregation(yearBuilder);
        nativeSearchQuery.setPageable(PageRequest.of(0,1));

        SearchHits<TempLincolnshireDocument> searchHits = elasticsearchOperations.search(nativeSearchQuery,TempLincolnshireDocument.class);
        Aggregations aggregations = searchHits.getAggregations();

        ParsedDateHistogram parsedDateHistogram = aggregations.get("year");
        List<ParsedDateHistogram.ParsedBucket> yearParsedBucketList = (List<ParsedDateHistogram.ParsedBucket>)parsedDateHistogram.getBuckets();

        List<Map<String, Object>> mapList = new LinkedList<>();
        for (ParsedDateHistogram.ParsedBucket yearParsedBucket : yearParsedBucketList) {
            String year = yearParsedBucket.getKeyAsString();
            ParsedDateHistogram monthParsedDateHistogram = yearParsedBucket.getAggregations().get("month");
            List<ParsedDateHistogram.ParsedBucket> monthParsedBucketList = (List<ParsedDateHistogram.ParsedBucket>)monthParsedDateHistogram.getBuckets();
            for (ParsedDateHistogram.ParsedBucket monthParsedBucket : monthParsedBucketList) {
                String month = monthParsedBucket.getKeyAsString();
                ParsedDateHistogram dayParsedDateHistogram = monthParsedBucket.getAggregations().get("day");
                List<ParsedDateHistogram.ParsedBucket> dayParsedBucketList = (List<ParsedDateHistogram.ParsedBucket>)dayParsedDateHistogram.getBuckets();
                for (ParsedDateHistogram.ParsedBucket dayParsedBucket : dayParsedBucketList) {
                    String day = dayParsedBucket.getKeyAsString();
                    ParsedDateHistogram hourParsedDateHistogram = dayParsedBucket.getAggregations().get("hour");
                    List<ParsedDateHistogram.ParsedBucket> hourParsedBucketList = (List<ParsedDateHistogram.ParsedBucket>) hourParsedDateHistogram.getBuckets();
                    for (ParsedDateHistogram.ParsedBucket hourParsedBucket: hourParsedBucketList) {
                        String hour = hourParsedBucket.getKeyAsString();

                        Aggregations subAggregations = hourParsedBucket.getAggregations();
                        ParsedAvg parsedAvg = subAggregations.get("avg");
                        ParsedMax parsedMax = subAggregations.get("max");
                        ParsedMin parsedMin = subAggregations.get("min");

                        Map<String,Object> map = new HashMap<>();

                        map.put("year",year);
                        map.put("month",month);
                        map.put("day",day);
                        map.put("hour",hour);
                        map.put("avg",parsedAvg.getValue());
                        map.put("max",parsedMax.getValue());
                        map.put("min",parsedMin.getValue());

                        mapList.add(map);
                    }
                }
            }
        }
        return mapList;
    }

    @Override
    public List<Map<String, Object>> aggDemo6(String dateRangeStart, String dateRangeEnd, int topNo, boolean isAsc, String aggField) {

        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("time").from(dateRangeStart).to(dateRangeEnd);
        System.out.println("rangeQueryBuilder:" + rangeQueryBuilder.toString());

        AbstractAggregationBuilder rootAggBuilder = null;

        if(aggField.equals("time")){
            rootAggBuilder = AggregationBuilders.dateHistogram(aggField).field(aggField).calendarInterval(DateHistogramInterval.MONTH).format("yyyy-MM").minDocCount(1)
                    .order(BucketOrder.aggregation("avg", isAsc));
        }else if(aggField.equals("name")){
            rootAggBuilder = AggregationBuilders.terms(aggField).field(aggField).order(BucketOrder.aggregation("avg", isAsc)).minDocCount(1).shardSize(1000000).executionHint("map");
        }

        AvgAggregationBuilder avgBuilder = AggregationBuilders.avg("avg").field("value");
        rootAggBuilder.subAggregation(avgBuilder);

        System.out.println("monthBuilder:" + rootAggBuilder.toString());

        NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(rangeQueryBuilder);
        nativeSearchQuery.addAggregation(rootAggBuilder);
        nativeSearchQuery.setPageable(PageRequest.of(0,1));

        SearchHits<TempLincolnshireDocument> searchHits = elasticsearchOperations.search(nativeSearchQuery,TempLincolnshireDocument.class);

        List<Map<String, Object>> mapList = new LinkedList<>();

        if(aggField.equals("time")){
            ParsedDateHistogram parsedDateHistogram = searchHits.getAggregations().get(aggField);
            List<ParsedDateHistogram.ParsedBucket> yearParsedBucketList = (List<ParsedDateHistogram.ParsedBucket>)parsedDateHistogram.getBuckets();
            for (ParsedDateHistogram.ParsedBucket parsedBucket : yearParsedBucketList) {
                String month = parsedBucket.getKeyAsString();
                ParsedAvg parsedAvg = parsedBucket.getAggregations().get("avg");
                Map<String, Object> map = new HashMap();
                map.put(month, parsedAvg.getValue());
                mapList.add(map);
                if(mapList.size() >= topNo){
                    break;
                }
            }
        }else if(aggField.equals("name")) {
            ParsedTerms parsedDateHistogram = searchHits.getAggregations().get(aggField);
            List<ParsedTerms.ParsedBucket> yearParsedBucketList = (List<ParsedTerms.ParsedBucket>)parsedDateHistogram.getBuckets();
            for (ParsedTerms.ParsedBucket parsedBucket : yearParsedBucketList) {
                String month = parsedBucket.getKeyAsString();
                ParsedAvg parsedAvg = parsedBucket.getAggregations().get("avg");
                Map<String, Object> map = new HashMap();
                map.put(month, parsedAvg.getValue());
                mapList.add(map);
                if(mapList.size() >= topNo){
                    break;
                }
            }
        }
        return mapList;
    }

}
